package xdrawer;

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import xdrawer.shape.AbstractSymbol;
import xdrawer.shape.Symbol;
import xdrawer.shape.SymbolType;

import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;


public class Main extends Application {
    private BorderPane root = new BorderPane();
    private VBox symbolBar = new VBox(5);
    private ScrollPane canvasPanel = new ScrollPane();
    private FlowCharCanvas canvas = new FlowCharCanvas(600, 800);

    private ArrayList<Symbol> flowchart = new ArrayList<>();

    @Override
    public void start(Stage primaryStage) throws Exception {

        Button btnProcess = new Button("处理");
        btnProcess.setMaxWidth(Double.MAX_VALUE);
        btnProcess.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                double x = Math.random() * canvas.getWidth() / 2;
                double y = Math.random() * canvas.getHeight() / 2;
                Symbol symbol = new Symbol(SymbolType.PROCESS, x, y, 100, 40, "Process\nTest");
                flowchart.add(symbol);
                canvas.draw();
            }
        });

        Button btnData = new Button("数据");
        btnData.setMaxWidth(Double.MAX_VALUE);
        btnData.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                double x = Math.random() * canvas.getWidth() / 2;
                double y = Math.random() * canvas.getHeight() / 2;
                Symbol symbol = new Symbol(SymbolType.START_END, x, y, 100, 40, "开始");
                flowchart.add(symbol);
                canvas.draw();
            }
        });

        Button btnCondition = new Button("判定");
        btnCondition.setMaxWidth(Double.MAX_VALUE);
        btnCondition.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                double x = Math.random() * canvas.getWidth() / 2;
                double y = Math.random() * canvas.getHeight() / 2;
                Symbol symbol = new Symbol(SymbolType.CONDITION, x, y, 100, 40, "判定");
                flowchart.add(symbol);
                canvas.draw();
            }
        });

        Button btnExport = new Button("导出图片(snapshot)");
        btnExport.setMaxWidth(Double.MAX_VALUE);
        btnExport.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                WritableImage image = root.getScene().snapshot(null);
                WritableImage img = canvas.snapshot(null,null);
                File file = new File("export.png");
                try {
                    ImageIO.write(SwingFXUtils.fromFXImage(img,null),"png",file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        symbolBar.setPadding(new Insets(10, 10, 10, 10));
        symbolBar.getChildren().addAll(btnProcess, btnData, btnCondition, btnExport);

        canvas.setFlowchart(flowchart);
        canvasPanel.setContent(canvas);

        root.setLeft(symbolBar);
        root.setCenter(canvasPanel);

        primaryStage.setTitle("XDrawer");
        primaryStage.setScene(new Scene(root, 1024, 800));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }

    /**
     * 绘图画布
     */
    private class FlowCharCanvas extends Canvas {
        private ArrayList<Symbol> flowchart;
        private GraphicsContext gc = null;
        private Symbol current = null;
        private ArrayList<Symbol> selectedSymbols = new ArrayList<>();

        public FlowCharCanvas(double width, double height) {
            super(width, height);

            this.gc = this.getGraphicsContext2D();
            clearCanvas();
            selectedSymbols.clear();

            this.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    // 获取鼠标指针按下处的对象
                    current = getSymbolContains(event.getX(), event.getY());

                    if (current == null) {
                        // 检测有没有同时按下Ctrl键
                        if (!event.isControlDown()) {
                            selectedSymbols.clear();  // 清除所有选中对象
                        }
                    } else {
                        if (event.isControlDown()) {
                            if (!selectedSymbols.contains(current)) {
                                selectedSymbols.add(current);
                            }
                        } else {
                            if (!selectedSymbols.contains(current)) {
                                selectedSymbols.clear();
                                selectedSymbols.add(current);
                            }
                            for (Symbol s : selectedSymbols) {
                                s.setDxToPointer(event.getX() - s.getX());
                                s.setDyToPointer(event.getY() - s.getY());
                            }

                        }
                    }

                    System.out.println("---------------------");
                    if(event.getClickCount()==2){
                        System.out.println("22222222222222");
                    }

                    canvas.draw();
                }
            });

            this.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    System.out.println("clicked!!!");
                    if(event.getClickCount()==2){
                        System.out.println("222222222222222222222222222222222");
                    }
                }
            });

            this.setOnMouseDragged(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.isControlDown()) {
                        return;
                    }
                    for (Symbol s : selectedSymbols) {
                        s.setX(event.getX() - s.getDxToPointer());
                        s.setY(event.getY() - s.getDyToPointer());
                    }
                    canvas.draw();
                }
            });
        }

        public void draw() {
            clearCanvas();

            for (Symbol symbol : flowchart) {
                symbol.draw(gc);
            }

            for (Symbol symbol : selectedSymbols) {
                symbol.drawSelectedBox(gc);
            }
        }

        public ArrayList<Symbol> getFlowchart() {
            return flowchart;
        }

        public void setFlowchart(ArrayList<Symbol> flowchart) {
            this.flowchart = flowchart;
        }

        //
        private void clearCanvas() {
            gc.clearRect(0, 0, this.getWidth(), this.getHeight());
            gc.setFill(Color.WHITE);
            gc.fillRect(0, 0, this.getWidth(), this.getHeight());
        }

        //
        private Symbol getSymbolContains(double x, double y) {
            for (int i = flowchart.size() - 1; i >= 0; i--) {
                Symbol s = flowchart.get(i);
                if (s.containsPoint(x, y)) {
                    s.setSelected(true);
                    return s;
                }
            }
            return null;
        }
    }

}
